from django.shortcuts import render

# Create your views here.
from django_redis import get_redis_connection
from rest_framework import status, mixins, serializers
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from rest_framework.viewsets import ModelViewSet, GenericViewSet
from users.models import User

from rest_framework_jwt.utils import jwt_decode_handler

from spits.models import Spit
from spits.serializers.lists import GetSpitListSerializers, RetriveSpitListSerializers


class SpitViewSet(ModelViewSet):
    '''Spit ModelViewSet'''

    queryset = Spit.objects.all()

    serializer_class = GetSpitListSerializers

    pagination_class = None

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)

        redis_conn1 = get_redis_connection('spit')
        if request.user.username:
            collected = redis_conn1.smembers('spit_flag_%s' % request.user.username)
            for data in serializer.data:
                pk = data['id']
                if str(pk).encode() in collected:
                    data['collected'] = True
        return Response(serializer.data)

    # def get_paginated_response(self, data):
    #     """
    #     Return a paginated style `Response` object for the given output data.
    #     """
    #     assert self.paginator is not None
    #     redis_conn1 = get_redis_connection('spit')
    #     collected = redis_conn1.smembers('spit_flag_%s' % self.request.user.username)
    #     redis_conn2 = get_redis_connection('humb')
    #     hasthumbup = redis_conn2.smembers('spit_flag_%s' % self.request.user.username)
    #
    #     for i in range(len(data)):
    #         user = data[i]['user']
    #         del data[i]['user']
    #         data[i]['userid'] = user.get('id')
    #         data[i]['nickname'] = user.get('nickname')
    #         data[i]['avatar'] = user.get('avatar')
    #         if collected:
    #             data[i]['collected'] = True
    #             data[i]['state'] = 1
    #         if hasthumbup:
    #             data[i]['hasthumbup'] = True
    #
    #     return self.paginator.get_paginated_response(data)

    def retrieve(self, request, *args, **kwargs):
        """
        rewrite retrieve method
        """
        pk = kwargs['pk']
        redis_conn2 = get_redis_connection('humb')
        hasthumbup = redis_conn2.smembers('spit_flag_%s' % request.user.username)
        redis_conn1 = get_redis_connection('spit')
        collected = redis_conn1.smembers('spit_flag_%s' % request.user.username)

        instance = self.get_object()
        serializer = self.get_serializer(instance)
        data = serializer.data
        del data['state']
        if not data.get('user'):
            data['userid'] = None
            data['nickname'] = None
            data['avatar'] = None
        else:
            user = data['user']
            del data['user']
            data['userid'] = user.get('id')
            data['nickname'] = user.get('nickname')
            data['avatar'] = user.get('avatar')
        if pk.encode() in collected:
            data['collected'] = True
        if pk.encode() in hasthumbup:
            data['hasthumbup'] = True
        return Response(data)

    @action(methods=['get'], detail=True)
    def children(self, request, pk):
        '''spit comment information'''
        try:
            spits = Spit.objects.filter(parent=pk)
            data_lists = []
            for spit in spits:
                serializer = RetriveSpitListSerializers(spit)
                data = serializer.data
                if not data.get('user'):
                    data['userid'] = None
                    data['nickname'] = None
                    data['avatar'] = None
                else:
                    user = data['user']
                    del data['user']
                    data['userid'] = user.get('id')
                    data['nickname'] = user.get('nickname')
                    data['avatar'] = user.get('avatar')
                    data_lists.append(data)
        except Exception:
            raise serializers.ValidationError('缺少比传参数')
        return Response(data_lists)


    def create(self, request, *args, **kwargs):
        token = self.request.auth
        content = self.request.data.get('content')
        parent = self.request.data.get('parent')

        if all([token,content,parent]):

            try:
                token_user = jwt_decode_handler(token)
                id = token_user['user_id']
            except Exception:
                raise serializers.ValidationError('用户非法')
            try:
                user = User.objects.get(id=id)
                Spit.objects.filter(user=user,parent=parent).create(content=content,user_id=id,parent_id=parent)
            except Exception:
                raise serializers.ValidationError('发布失败')
            return Response({"content":content,"parent":parent},status=status.HTTP_201_CREATED)

        elif content:
            try:
                Spit.objects.filter(parent__id=1).create(content=content,parent_id=1)
            except Exception:
                raise serializers.ValidationError('发布失败')

            return Response({"content":content,"parent":parent},status=status.HTTP_201_CREATED)

        raise serializers.ValidationError('不合法')

    lookup_value_regex = '\d+'


class SpitCollectView(mixins.CreateModelMixin,mixins.UpdateModelMixin,GenericViewSet):
    '''收藏、取消收藏'''

    permission_classes = [IsAuthenticated]
    serializer_class = GetSpitListSerializers

    @action(methods=['put'], detail=True)
    def collect(self,request,pk):
        '''收藏、取消收藏'''
        username = request.user.username

        # 将这句话提到前面最开始的位置:
        redis_conn = get_redis_connection('spit')
        # 进入函数后, 先获取存储在 redis 中的数据
        send_flag = redis_conn.smembers('spit_flag_%s'%username)
        # 查看数据是否存在
        if pk.encode() in send_flag:

            redis_conn.srem('spit_flag_%s' %username,pk)

            data = {"id": pk, "message": "ok", "success": True}

        else:
            # 保存点赞信息
            redis_conn.sadd('spit_flag_%s' %username,pk)

            data = {"id": pk, "message": "ok", "success": True}

        return Response(data, status=status.HTTP_201_CREATED)


    @action(methods=['put'], detail=True)
    def updatethumbup(self, request, pk):
        '''点赞、取消点赞'''

        username = request.user.username
        # 将这句话提到前面最开始的位置:
        redis_conn = get_redis_connection('humb')
        # 进入函数后, 先获取存储在 redis 中的数据
        send_flag = redis_conn.smembers('spit_flag_%s'%username)
        # 查看数据是否存在
        if pk.encode() in send_flag:
            redis_conn.srem('spit_flag_%s'%username,pk)
            data = {"id": pk, "message": "ok", "success": True}
            try:
                instances = Spit.objects.get(id=pk)
                if instances.thumbup != 0:
                    instances.thumbup -= 1
                    instances.save()
            except Exception:
                data = {"id": pk, "message": "数据库写入失败", "success": False}
            return Response(data, status=status.HTTP_201_CREATED)

        redis_conn.sadd('spit_flag_%s' %username,pk)
        data = {"id": pk, "message": "ok", "success": True}

        try:
            instances = Spit.objects.get(id=pk)
            instances.thumbup += 1
            instances.save()
        except Exception:
            data = {"id": pk, "message": "数据库写入失败", "success": False}

        return Response(data, status=status.HTTP_201_CREATED)


    lookup_value_regex = '\d+'